package tech

import (
	"ssp/set"
)

func (s *Solve) WRectangle(g *Grid) (used bool, results []*Result) {
	return g.wRectangle()
}

func (g *Grid) wRectangle() (used bool, results []*Result) {
	pairs := g.findBiPairs()
	for _, pair := range pairs {
		p0 := g.rows[pair[0].rowNum].cells[pair[1].colNum]
		p1 := g.rows[pair[1].rowNum].cells[pair[0].colNum]
		//fmt.Println(p0, p1, pair)
		for _, p := range []*Cell{p0, p1} {
			box := g.boxes[p.boxNum]
			for _, cand := range pair[0].cands.GetList() {
				bok, emptyCells := verifyEmptyBox(box, cand, p.rowNum, p.colNum)
				if !bok {
					continue
				}
				rmCands := pair[0].cands.Diff(set.NewSet(cand))
				rok, rmCells := g.canRemoveSeenCands(rmCands, pair[:])
				if !rok {
					continue
				}
				used = true
				if OUTPUTRESULT {
					result := new(Result)
					result.setStrategyName("W-Rectangle")
					result.addRemoved(rmCands, rmCells)
					g1 := result.getHelpCandsGroup()
					g1.add(set.NewSet(cand), emptyCells)
					g1.add(set.NewSet(cand), pair[:])
					g2 := result.getHelpCandsGroup()
					g2.add(rmCands, pair[:])
					//result.addHelpCells(pair[:])
					result.addHelpHouses([]*House{&g.boxes[emptyCells[0].boxNum]})
					results = append(results, result)
				}
				if CHANGE {
					removeCands(rmCands, rmCells)
				}
				if !EXHAUSTIVE {
					return
				}
			}
		}
	}

	return
}

func (g *Grid) findBiPairs() (pairs [][2]*Cell) {
	biCells := make(map[set.Set][]*Cell)
	for _, cell := range g.allCells {
		if cell.cands.Count() != 2 {
			continue
		}
		biCells[cell.cands] = append(biCells[cell.cands], cell)
	}
	for _, values := range biCells {
		for _, pair := range combine(values, 2) {
			if isSameHouse(pair[:]) {
				continue
			}
			if pair[0].boxNum%3 == pair[1].boxNum%3 {
				continue
			}
			if pair[0].boxNum/3 == pair[1].boxNum/3 {
				continue
			}
			pairs = append(pairs, [2]*Cell{pair[0], pair[1]})
		}
	}
	return
}

/*
	func (g *Grid) verifyEmptyRectangle(pair [2]*Cell) (ok bool, cand int, emptyCells []*Cell) {
		p0 := g.rows[pair[0].rowNum].cells[pair[1].colNum]
		p1 := g.rows[pair[1].rowNum].cells[pair[0].colNum]
		for _, p := range []*Cell{p0, p1} {
			box := g.boxes[p.boxNum]
			for _, cand := range pair[0].cands.GetList() {
				if !isEmptyBox(box, cand, p.rowNum, p.colNum) {
					continue
				}
			}
		}
		return
	}
*/
func verifyEmptyBox(box House, cand int, rowNum, colNum int) (ok bool, emptyCells []*Cell) {
	for _, cell := range box.cells {
		if cell.solved() && cell.value == cand+1 {
			return
		}
		if cell.cands.Has(cand) {
			if cell.rowNum == rowNum || cell.colNum == colNum {
				emptyCells = append(emptyCells, cell)
			} else {
				return
			}
		}
	}
	ok = true
	return
}
